package controllers

import (
	"encoding/json"
	"translate_backend/AppCommon"
	"translate_backend/AppConfig"
	controllers "translate_backend/controllers/BaseController"
	"translate_backend/db"
	"translate_backend/models"

	//utils "translate/translate_backend/utils"
	"archive/zip"
	"fmt"
	"io/ioutil"
	"os"
	"strings"
	"time"

	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/gin-gonic/gin"
	"gopkg.in/mgo.v2/bson"
)

type LangCon struct {
	controllers.BaseController
	//services.Service
}

// 获取全部(分页)/搜索
func (con *LangCon) GetLangItems(c *gin.Context) {

	//项目ID
	projID := c.Query("projID")
	println("this.curProjID:", projID)
	if projID == "" {
		con.ServeError(403, "项目ID为空", nil, c)
		return
	}
	//查询
	keyword := c.Query("keyword")

	limitFields := map[string]int{"_id": 0}

	if keyword == "" {
		//根据 项目id查询
		//q := map[string]interface{}{"projID": projID}
		con.GetAllByPage(projID, nil, limitFields, []string{"zhs"}, c)
	} else {
		//搜索
		condition := bson.M{"$or": []bson.M{bson.M{"langkey": bson.RegEx{keyword, "."}},
			bson.M{"zhs": bson.RegEx{keyword, "."}},
			bson.M{"langkey": bson.RegEx{keyword, "."}}}}

		con.GetAllByPage(projID, condition, limitFields, []string{"sort"}, c)
	}

}

// 获取单条
func (con *LangCon) GetLangItemDetail(c *gin.Context) {
	//con.GetObjectByID("langItem", nil, c)

	var obj models.LangItem

	err := c.ShouldBindJSON(&obj)

	if err == nil {

		if obj.ProjID == "" {
			con.ServeError(403, "项目ID为空", nil, c)
			return
		}

		//表名为ProjID
		con.GetObjectByID(obj.ProjID, nil, c)
	} else {
		//c.Data["json"] = err.Error()
		con.ServeError(403, "", nil, c)
	}

}

// --------POST---------
// 创建
func (con *LangCon) Create(c *gin.Context) {

	//var obj models.LangItem = new(models.LangItem) //这个是指针
	//obj := models.LangItem{} //值类型

	var obj models.LangItem

	err := c.ShouldBindJSON(&obj)

	if err == nil {

		if obj.ProjID == "" {
			con.ServeError(403, "项目ID为空", nil, c)
			return
		}

		obj.SetupInitValues()
		//表名为ProjID
		res := db.InsertOne(obj, obj.ProjID)
		if res {
			con.ServeSuccess(obj, "", c)
		} else {
			con.ServeError(500, "词条key可能重复", nil, c)
		}

	} else {
		//c.Data["json"] = err.Error()
		con.ServeError(403, "", nil, c)
	}
}

// 更新
func (con *LangCon) Update(c *gin.Context) {

	projID := c.DefaultQuery("projID", "")
	println("projID:", projID)

	//ShouldBindXXX不能多次调用
	//err := c.ShouldBindJSON(&obj)
	if projID == "" {
		con.ServeError(403, "项目ID为空", nil, c)
		return
	}
	//表名为ProjID
	con.UpdateObjectByID(projID, c)

}

// 删除
func (con *LangCon) Delete(c *gin.Context) {

	projID := c.DefaultQuery("projID", "")
	println("projID:", projID)

	//ShouldBindXXX不能多次调用
	//err := c.ShouldBindJSON(&obj)
	if projID == "" {
		con.ServeError(403, "项目ID为空", nil, c)
		return
	}
	//表名为ProjID
	con.DeleteObjectByID(projID, c)

}

// 导入
func (con *LangCon) ImportLocalFile(c *gin.Context) {

}

// 旧版, 导出可下载文件(流导出)
func (con *LangCon) ExportLangFile(c *gin.Context) {

	platform := c.Param("platform") //:id 要匹配路由里面的命名

	var res []models.LangItem
	count := db.FindAll("langItem", nil, map[string]int{"_id": 0, "id": 0, "createDate": 0, "projID": 0, "groupID": 0, "sort": 0}, []string{"langkey"}, &res, 0, false)
	var zhstr = ""
	var enstr = ""
	var tempStr = ""
	var extension = "strings" //文件后缀名
	println("count:", count)

	//iOS需要替换 zh-Hans.strings ,en
	if platform == "iOS" {

		for _, item := range res {
			//简体中文
			tempStr = "\"" + item.Langkey + "\" = \"" + item.Zhs + "\";\n"
			zhstr = zhstr + tempStr
			//英文
			tempStr = "\"" + item.Langkey + "\" = \"" + item.En + "\";\n"
			enstr = enstr + tempStr
		}

		zhstr = strings.Replace(zhstr, "%s", "%@", -1)
		enstr = strings.Replace(enstr, "%s", "%@", -1)
	} else {
		//android是xml
		extension = "xml"

		for _, item := range res {
			//简体中文
			tempStr = "<string name=\"" + item.Langkey + "\">" + item.Zhs + "</string>\n"
			zhstr = zhstr + tempStr
			//英文
			tempStr = "<string name=\"" + item.Langkey + "\">" + item.En + "</string>\n"
			enstr = enstr + tempStr
		}

		zhstr = "<resources>\n" + zhstr + "</resources>"
		enstr = "<resources>\n" + enstr + "</resources>"
	}

	// println("zhstr:", zhstr)
	// println("enstr:", enstr)
	//压缩 zip
	zipW := zip.NewWriter(c.Writer)
	defer zipW.Close()

	c.Writer.Header().Set("Content-Type", "application/zip")
	c.Writer.Header().Set("attachment", "filename=words.zip")

	controllers.AddZip(zipW, "zh-Hans."+extension, zhstr)
	controllers.AddZip(zipW, "en."+extension, enstr)

}

// 导出可下载文件 (新版,极简格式)
func (con *LangCon) ExportLangItems(c *gin.Context) {

	platform := c.Param("platform") //  平台
	projID := c.Param("projID")     //  项目ID

	var postParams map[string]interface{}

	//转换json失败,参数有问题
	if perr := c.ShouldBindJSON(&postParams); perr != nil {
		con.ServeError(500, "参数格式有误", nil, c)
		return
	}

	//获取转换的语言列表
	langs, ok := postParams["langs"].([]interface{})
	if ok == false {
		con.ServeError(500, "参数有误,请检查导出语言设置", nil, c)
		return
	}

	langDic := make(map[string]int)
	for _, v := range langs {
		langDic[v.(string)] = 1
	}

	// for k,v := range langDic {
	// 	fmt.Println(k,":",v)
	// }

	//创建本次导出根目录
	timeDes := time.Now().Format("2006-01-02_15_04_05")  // 小心:号被转义
	exportRootDir := AppConfig.ExportDir + "/" + timeDes //导出根目录
	exportDir := exportRootDir + "/" + platform          //存放语言文件的目录
	err := os.MkdirAll(exportDir, 0775)
	if err != nil {
		con.ServeError(500, "导出文件夹创建失败,请检查文件读写权限", nil, c)
		return
	}

	//导出下载压缩包
	exportZipPath := exportRootDir + "/" + platform + ".zip"

	//按项目导出
	//q := map[string]interface{}{"projID": projID}

	var res []models.LangItem
	itemsCount := db.FindAll(projID, nil, map[string]int{"_id": 0, "id": 0, "createDate": 0, "projID": 0, "groupID": 0, "sort": 0}, []string{"langkey"}, &res, 0, true)

	//--------开始导出----------

	zhs := "" // { name: "简体中文", indef: "zhs" },
	zht := "" // { name: "繁体中文", indef: "zht" },
	en := ""  // { name: "英语", indef: "en" },
	de := ""  // { name: "德语", indef: "de" },
	ja := ""  // { name: "日语", indef: "ja" },
	uk := ""  // { name: "乌克兰", indef: "uk" },
	es := ""  // { name: "西班牙", indef: "es" },
	it := ""  // { name: "意大利", indef: "it" },
	pl := ""  // { name: "波兰", indef: "pl" },
	ko := ""  // { name: "韩语", indef: "ko" },
	ru := ""  // { name: "俄语", indef: "ru" },
	fr := ""  // { name: "法语", indef: "fr" },
	idn := "" // { name: "印度尼西亚", indef: "idn" },
	pt := ""  // { name: "葡萄牙", indef: "pt" },
	vi := ""  // { name: "越南", indef: "vi" },
	iw := ""  // { name: "希伯来语", indef: "iw" },
	ar := ""  // { name: "阿拉伯语", indef: "ar" },
	km := ""  // { name: "高棉语", indef: "km" },
	in := ""  // { name: "印尼", indef: "in" },
	cs := ""  // { name: "捷克", indef: "cs" },
	az := ""  // { name: "阿塞拜疆语", indef: "az" },
	nl := ""  // { name: "荷兰", indef: "nl" },
	lo := ""  // { name: "老挝", indef: "lo" },
	tr := ""  // { name: "土耳其", indef: "tr" },
	th := ""  // { name: "泰语", indef: "th" },
	bn := ""  // { name: "孟加拉", indef: "bn" },
	da := ""  // { name: "丹麦", indef: "da" },
	fa := ""  // { name: "波斯语", indef: "fa" },
	hi := ""  // { name: "印地语", indef: "hi" },
	ka := ""  // { name: "格鲁吉亚", indef: "ka" },
	sr := ""  // { name: "塞尔维亚", indef: "sr" },
	mn := ""  // { name: "蒙古", indef: "mn" },
	sv := ""  // { name: "瑞典", indef: "sv" },
	mk := ""  // { name: "马其顿", indef: "mk" }

	//iOS需要替换 zh-Hans.strings ,en

	//是否使用中文key
	isIOSuseZhKey, _ := postParams["isIOSuseZhKey"].(bool)

	for index, item := range res {

		//简体中文
		if langDic["zhs"] == 1 {
			generateLngFile(exportDir, platform, "zhs", &item, item.Zhs, isIOSuseZhKey, &zhs, index == itemsCount-1)
		}

		//繁体中文
		if langDic["zht"] == 1 {
			generateLngFile(exportDir, platform, "zht", &item, item.Zht, isIOSuseZhKey, &zht, index == itemsCount-1)
		}

		//英语
		if langDic["en"] == 1 {
			generateLngFile(exportDir, platform, "en", &item, item.En, isIOSuseZhKey, &en, index == itemsCount-1)
		}

		//德语
		if langDic["de"] == 1 {
			generateLngFile(exportDir, platform, "de", &item, item.De, isIOSuseZhKey, &de, index == itemsCount-1)
		}

		//日语
		if langDic["ja"] == 1 {
			generateLngFile(exportDir, platform, "ja", &item, item.Ja, isIOSuseZhKey, &ja, index == itemsCount-1)
		}

		//乌克兰
		if langDic["uk"] == 1 {
			generateLngFile(exportDir, platform, "uk", &item, item.Uk, isIOSuseZhKey, &uk, index == itemsCount-1)
		}

		//西班牙
		if langDic["es"] == 1 {
			generateLngFile(exportDir, platform, "es", &item, item.Es, isIOSuseZhKey, &es, index == itemsCount-1)
		}

		//意大利
		if langDic["it"] == 1 {
			generateLngFile(exportDir, platform, "it", &item, item.It, isIOSuseZhKey, &it, index == itemsCount-1)
		}

		//波兰
		if langDic["pl"] == 1 {
			generateLngFile(exportDir, platform, "pl", &item, item.Pl, isIOSuseZhKey, &pl, index == itemsCount-1)
		}

		//韩语
		if langDic["ko"] == 1 {
			generateLngFile(exportDir, platform, "ko", &item, item.Ko, isIOSuseZhKey, &ko, index == itemsCount-1)
		}

		//俄语
		if langDic["ru"] == 1 {
			generateLngFile(exportDir, platform, "ru", &item, item.Ru, isIOSuseZhKey, &ru, index == itemsCount-1)
		}

		//法语
		if langDic["fr"] == 1 {
			generateLngFile(exportDir, platform, "fr", &item, item.Fr, isIOSuseZhKey, &fr, index == itemsCount-1)
		}

		//印度尼西亚
		if langDic["idn"] == 1 {
			generateLngFile(exportDir, platform, "idn", &item, item.Idn, isIOSuseZhKey, &idn, index == itemsCount-1)
		}

		//葡萄牙
		if langDic["pt"] == 1 {
			generateLngFile(exportDir, platform, "pt", &item, item.Pt, isIOSuseZhKey, &pt, index == itemsCount-1)
		}

		//越南
		if langDic["vi"] == 1 {
			generateLngFile(exportDir, platform, "vi", &item, item.Vi, isIOSuseZhKey, &vi, index == itemsCount-1)
		}

		//希伯来语
		if langDic["iw"] == 1 {
			generateLngFile(exportDir, platform, "iw", &item, item.Iw, isIOSuseZhKey, &iw, index == itemsCount-1)
		}

		//阿拉伯语
		if langDic["ar"] == 1 {
			generateLngFile(exportDir, platform, "ar", &item, item.Ar, isIOSuseZhKey, &ar, index == itemsCount-1)
		}

		//高棉语
		if langDic["km"] == 1 {
			generateLngFile(exportDir, platform, "km", &item, item.Km, isIOSuseZhKey, &km, index == itemsCount-1)
		}

		//印尼
		if langDic["in"] == 1 {
			generateLngFile(exportDir, platform, "in", &item, item.In, isIOSuseZhKey, &in, index == itemsCount-1)
		}

		//捷克
		if langDic["cs"] == 1 {
			generateLngFile(exportDir, platform, "cs", &item, item.Cs, isIOSuseZhKey, &cs, index == itemsCount-1)
		}

		//阿塞拜疆语
		if langDic["az"] == 1 {
			generateLngFile(exportDir, platform, "az", &item, item.Az, isIOSuseZhKey, &az, index == itemsCount-1)
		}

		//荷兰
		if langDic["nl"] == 1 {
			generateLngFile(exportDir, platform, "nl", &item, item.Nl, isIOSuseZhKey, &nl, index == itemsCount-1)
		}

		//老挝
		if langDic["lo"] == 1 {
			generateLngFile(exportDir, platform, "lo", &item, item.Lo, isIOSuseZhKey, &lo, index == itemsCount-1)
		}

		//土耳其
		if langDic["tr"] == 1 {
			generateLngFile(exportDir, platform, "tr", &item, item.Tr, isIOSuseZhKey, &tr, index == itemsCount-1)
		}

		//泰语
		if langDic["th"] == 1 {
			generateLngFile(exportDir, platform, "th", &item, item.Th, isIOSuseZhKey, &th, index == itemsCount-1)
		}

		//孟加拉
		if langDic["bn"] == 1 {
			generateLngFile(exportDir, platform, "bn", &item, item.Bn, isIOSuseZhKey, &bn, index == itemsCount-1)
		}

		//丹麦
		if langDic["da"] == 1 {
			generateLngFile(exportDir, platform, "da", &item, item.Da, isIOSuseZhKey, &da, index == itemsCount-1)
		}

		//波斯语
		if langDic["fa"] == 1 {
			generateLngFile(exportDir, platform, "fa", &item, item.Fa, isIOSuseZhKey, &fa, index == itemsCount-1)
		}

		//印地语
		if langDic["hi"] == 1 {
			generateLngFile(exportDir, platform, "hi", &item, item.Hi, isIOSuseZhKey, &hi, index == itemsCount-1)
		}

		//格鲁吉亚
		if langDic["ka"] == 1 {
			generateLngFile(exportDir, platform, "ka", &item, item.Ka, isIOSuseZhKey, &ka, index == itemsCount-1)
		}

		//塞尔维亚
		if langDic["sr"] == 1 {
			generateLngFile(exportDir, platform, "sr", &item, item.Sr, isIOSuseZhKey, &sr, index == itemsCount-1)
		}

		//蒙古
		if langDic["mn"] == 1 {
			generateLngFile(exportDir, platform, "mn", &item, item.Mn, isIOSuseZhKey, &mn, index == itemsCount-1)
		}

		//瑞典
		if langDic["sv"] == 1 {
			generateLngFile(exportDir, platform, "sv", &item, item.Sv, isIOSuseZhKey, &sv, index == itemsCount-1)
		}

		//马其顿
		if langDic["mk"] == 1 {
			generateLngFile(exportDir, platform, "mk", &item, item.Mk, isIOSuseZhKey, &mk, index == itemsCount-1)
		}

		index++
	}

	// //压缩目录
	f, err := os.Open(exportDir)
	if err != nil {
		fmt.Println("打开压缩文件失败", err)
	}
	defer f.Close()
	var files = []*os.File{f}
	exportErr := controllers.Compress(files, exportZipPath)

	if exportErr != nil {
		con.ServeError(503, "生成导出文件失败", nil, c)
	} else {
		exportURLPath := AppCommon.HostURL + strings.Trim(exportZipPath, ".")
		println("下载地址:", exportURLPath)
		con.ServeSuccess(exportURLPath, "生成文件成功", c)
	}

}

// iOS/Android生成,后续按需求加上web
// @ saveDir 保存的目录
// @ indef 文件命名
// @ langItem 语言类
// @ content 拼接的翻译文本
// @ isIOSuseZhKey 是否使用中文作为key
// @ result 用于本次拼接
// @ isWiteToFile 是否写入文件(最后一项完成,写入文件)
// @ zipW 压缩writer
func generateLngFile(
	saveDir string,
	platform string,
	indefName string,
	langItem *models.LangItem,
	content string,
	isIOSuseZhKey bool,
	result *string,
	isWiteToFile bool) {

	var key = ""

	// println(*result)

	//iOS
	if platform == "iOS" {
		if isIOSuseZhKey {
			key = langItem.Zhs
		} else {
			key = langItem.Langkey
		}

		var tempStr = "\"" + key + "\" = \"" + content + "\";\n"
		tempStr = strings.Replace(tempStr, "%s", "%@", -1) //转换占位符
		*result = *result + tempStr

	} else if platform == "android" {
		key = langItem.Langkey
		var tempStr = "<string name=\"" + key + "\">" + content + "</string>\n"
		*result = *result + tempStr
	}

	if isWiteToFile {

		finalExportPath := ""

		//不同的平台导出目录结构不一样
		if platform == "iOS" {
			subExportDir := saveDir + "/" + indefName + ".lproj"
			err := os.MkdirAll(subExportDir, 0775)
			if err != nil {
				return
			}
			finalExportPath = subExportDir + "/" + "Localizable.strings"
		} else if platform == "android" {
			finalExportPath = saveDir + "/" + indefName + ".xml"
			*result = "<resources>\n" + *result + "</resources>"
		}

		//写入文件
		content := []byte(*result)
		err := ioutil.WriteFile(finalExportPath, content, 0644)
		if err != nil {
			//    panic(err)
		}

		//controllers.AddZip(zipW, indefName+".string", *result)
	}
}

// 本地导出
func (con *LangCon) ExportiOSJsonFile(c *gin.Context) {

	xlsx, err := excelize.OpenFile("./xcurrency_111.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}

	//语种
	var langs []string

	// 根据名字获取Sheet的内容.
	rows := xlsx.GetRows("strings") //

	//第一行是语种名
	langRow := rows[0]
	for _, colCell := range langRow {
		if colCell == "" {
			continue
		}

		langs = append(langs, colCell)
	}

	var key string
	var value string

	var zhstr = ""
	var tempStr = ""
	for rowIndex, row := range rows {

		if rowIndex > 1 {
			for cellIndex, colCell := range row {

				if cellIndex == 0 {
					key = colCell
				}

				if cellIndex == 17 {
					value = colCell
					//简体中文
					tempStr = "\"" + key + "\" = \"" + value + "\";\n"
					zhstr = zhstr + tempStr
				}

			}
		}
	}
	zhstr = strings.Replace(zhstr, "%s", "%@", -1)

	//println("count:", zhstr)
	//
	//压缩 zip
	zipW := zip.NewWriter(c.Writer)
	defer zipW.Close()

	c.Writer.Header().Set("Content-Type", "application/zip")
	c.Writer.Header().Set("attachment", "filename=words.zip")

	controllers.AddZip(zipW, "zh-Hans."+"strings", zhstr)

}

//------------导入功能------

// 从excel导入
func (con *LangCon) ImportLocalExcel(c *gin.Context) {

	xlsx, err := excelize.OpenFile("./zlsftq.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}

	// 根据名字获取Sheet的内容.
	rows := xlsx.GetRows("sheet") //
	obj := models.LangItem{}
	total := 0
	for rowIndex, row := range rows {

		if rowIndex >= 1 {

			obj.SetupInitValues()
			lanKey := ""
			for cellIndex, colCellStr := range row {

				colCell := strings.TrimSpace(colCellStr)

				//中文 zhs
				if cellIndex == 1 {
					//fmt.Println(colCell)
					obj.Zhs = colCell
				} else if cellIndex == 2 {
					//fmt.Println(colCell)
					obj.En = colCell
					lanKey = strings.Replace(colCell, " ", "_", -1) //key字符串之间用_连接
					// 特殊符号处理 ' / % ? -  ： : !
					lanKey = strings.Replace(lanKey, "!", "", -1)
					lanKey = strings.Replace(lanKey, "'", "", -1)
					lanKey = strings.Replace(lanKey, "?", "", -1)
					lanKey = strings.Replace(lanKey, ":", "", -1)
					lanKey = strings.Replace(lanKey, "：", "", -1)
					lanKey = strings.Replace(lanKey, "/", "_", -1)
					lanKey = strings.Replace(lanKey, "-", "_", -1)
				} else if cellIndex == 3 {
					// fmt.Println(colCell)
					obj.Ja = colCell
				} else if cellIndex == 4 {
					// fmt.Println(colCell)
					obj.De = colCell
				} else if cellIndex == 5 {
					// fmt.Println(colCell)
					obj.Ko = colCell
				}

			}

			//如果英文长度大于15,不能做key
			if len(lanKey) > 30 {
				obj.Langkey = "a_" + obj.ID
			} else {
				obj.Langkey = lanKey
			}

			//插入,表名为ProjID
			res := db.InsertOne(obj, "5f8c9322938fb12fee1385f1")
			if res {
				//fmt.Println("插入成功:")
				total = total + 1
			} else {
				fmt.Println("插入失败,重复:", obj.Zhs)
			}

		}
	}

	fmt.Println("一共插入条数:", total)

}

// 从josn 导入全部(重新导入)
func (con *LangCon) ImportWithJson(c *gin.Context) {

	// f, err := os.Open("./allLang.json")
	// if err != nil {

	// 	fmt.Println("json文件读取错误")
	// }

	var langArr []models.LangItem
	data, _ := io.ReadFile("./allLang.json")
	_ = json.Unmarshal(data, &langArr)

	// if err = json.NewDecoder(r).Decode(langArr); err != nil {
	// 	fmt.Println("解析错误")
	// }

	//fmt.Println("解析到的数组:", langArr)

	col := "5f8c9322938fb12fee1385f1" //表名
	for _, lang := range langArr {
		lang.SetupInitValues()

		//表名为ProjID
		res := db.InsertOne(lang, col)
		if res {
			//con.ServeSuccess(obj, "", c)
		} else {
			fmt.Println("插入失败:", lang.Langkey)
		}

	}

}

// 从excel导入更新 (只有中英)
func (con *LangCon) UpdateLocalExcel(c *gin.Context) {

	xlsx, err := excelize.OpenFile("./z校对过1114.xlsx")
	if err != nil {
		fmt.Println(err)
		return
	}

	// 根据名字获取Sheet的内容.
	rows := xlsx.GetRows("Android") //

	total := 0
	for rowIndex, row := range rows {

		if rowIndex >= 1 {

			obj := make(map[string]string) //models.LangItem{}
			lanKey := ""
			for cellIndex, colCellStr := range row {

				colCell := strings.TrimSpace(colCellStr)

				//中文 zhs
				if cellIndex == 0 {
					//fmt.Println("key:", colCell)
					lanKey = colCell
					obj["lanKey"] = colCell
				} else if cellIndex == 1 {
					//fmt.Println("中文:", colCell)
					obj["zhs"] = colCell

				} else if cellIndex == 2 {
					//fmt.Println("英文:", colCell)
					obj["en"] = colCell
				}

			}

			//有key的话
			if len(lanKey) > 1 {
				//fmt.Println("对象:", obj)
				//插入,表名为ProjID
				res := db.UpdateOneByLangkey(lanKey, "5f8c9322938fb12fee1385f1", obj)
				if res {
					//fmt.Println("更新成功:")
					total = total + 1
				} else {
					fmt.Println("插入失败:", obj["lanKey"])
				}
			}

		}
	}

	fmt.Println("一共插入条数:", total)

}
